package com.naiterui.ehp.bs.payment.service.impl;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.naiterui.ehp.bp.bo.payment.NotifyBusinessRefundBO;
import com.naiterui.ehp.bp.bo.payment.NotifyBusinessRequestBO;
import com.naiterui.ehp.bp.constants.PayStatus;
import com.naiterui.ehp.bp.support.utils.JsonMapper;
import com.naiterui.ehp.bp.utils.date.DateUtil;
import com.naiterui.ehp.bp.utils.payment.bo.NotifyBusinessPayBO;
import com.naiterui.ehp.bs.payment.entity.PayInfo;
import com.naiterui.ehp.bs.payment.entity.RefundInfo;
import com.naiterui.ehp.bs.payment.exception.ExceptionCodes;
import com.naiterui.ehp.bs.payment.exception.PayStatusException;
import com.naiterui.ehp.bs.payment.exception.PaymentBusinessException;
import com.naiterui.ehp.bs.payment.repository.IPayInfoRepository;
import com.naiterui.ehp.bs.payment.repository.IRefundInfoRepository;
import com.naiterui.ehp.bs.payment.service.INotifyBusinessService;
import com.naiterui.ehp.bs.payment.service.IRecoverNotifyBusinessService;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * <pre>
 * 支付成功和退款成功回调业务系统
 * </pre>
 *
 * @author 王泽浩
 * @since 1.0.0
 */
@Service
@Slf4j
@AllArgsConstructor
public class NotifyBusinessServiceImpl implements INotifyBusinessService {

    private final IPayInfoRepository payInfoRepository;
    private final IRefundInfoRepository refundInfoRepository;
    private final IRecoverNotifyBusinessService recoverNotifyBusinessService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void notifyBusinessPay(String orderSn) throws PaymentBusinessException {
        PayInfo payInfo = this.payInfoRepository.findByOrderSn(orderSn);
        if (null == payInfo) {
            log.warn("订单不存在，不能通知业务系统。orderSn:{}", orderSn);
            throw new PaymentBusinessException(ExceptionCodes.PAY_ORDER_NOT_FIND);
        }
        Integer payInfoStatus = payInfo.getStatus();
        log.info("回调业务系统 orderSn:{} tradeSn:{} status:{}", orderSn, payInfo.getTradeSn(), payInfoStatus);
        // 支付结果回调业务系统
        String notifyBusinessUrl = payInfo.getNotifyBusinessUrl();
        NotifyBusinessPayBO notifyBusinessPayBO = NotifyBusinessPayBO.builder()
                                                                     // 业务订单号
                                                                     .orderSn(orderSn)
                                                                     // 订单类型
                                                                     .orderType(payInfo.getType())
                                                                     // 是否支付成功
                                                                     .payStatus(
                                                                             payInfoStatus == PayStatus.PAY_SUCCESS.getValue() ? NotifyBusinessPayBO.PAY_SUCCESS : NotifyBusinessPayBO.PAY_FAIL)
                                                                     // 订单状态
                                                                     .orderStatus(payInfoStatus)
                                                                     // 支付完成时间
                                                                     .payTime(DateUtil.formatDate(payInfo.getPayTime(),
                                                                                                  DateUtil.DATE_TIME_FORMAT))
                                                                     // 订单金额
                                                                     .totalFee(payInfo.getPrice().intValue())
                                                                     // 用户标识
                                                                     .userId(payInfo.getUserId())
                                                                     // 支付流水号
                                                                     .tradeSn(payInfo.getTradeSn())
                                                                     // 渠道名称
                                                                     .payChannelName("微信支付")
                                                                     // 上游系统订单号
                                                                     .channelTradeSn(payInfo.getChannelTradeSn()).build();
        NotifyBusinessRequestBO notifyBusinessRequest = new NotifyBusinessRequestBO(orderSn, null, NotifyBusinessRequestBO.NOTIFY_TYPE_PAY,
                                                                                    notifyBusinessUrl, JsonMapper.toJson(notifyBusinessPayBO));
        this.recoverNotifyBusinessService.asyncNotifyBusiness(notifyBusinessRequest);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void notifyBusinessRefund(String refundOrderSn) {
        log.info("退款状态通知业务系统。refundOrderSn:{}", refundOrderSn);
        RefundInfo refundInfo = this.refundInfoRepository.findFirstByRefundOrderSnOrderByCreatedAtDesc(refundOrderSn);
        if (null == refundInfo) {
            log.warn("订单退款信息不存在，不能通知业务系统。refundOrderSn:{}", refundOrderSn);
            return;
        }
        String orderSn = refundInfo.getOrderSn();
        Integer refundInfoStatus = refundInfo.getStatus();
        if (RefundInfo.ORDER_STATUS_WAIT == refundInfoStatus) {
            log.warn("订单状态为待退款，不同步业务系统。refundOrderSn:{}", refundOrderSn);
            throw new PayStatusException(String.format("订单状态为待退款，不同步业务系统。refundOrderSn:%s", refundOrderSn));
        }
        PayInfo payInfo = this.payInfoRepository.findByOrderSn(orderSn);
        // 支付结果回调业务系统
        String notifyBusinessUrl = refundInfo.getNotifyBusinessUrl();
        NotifyBusinessRefundBO notifyBusinessRefundBO = NotifyBusinessRefundBO.builder()
                                                                              // 用户标识
                                                                              .userId(payInfo.getUserId())
                                                                              // 订单状态
                                                                              .status(payInfo.getStatus())
                                                                              // 订单号
                                                                              .orderSn(orderSn)
                                                                              .refundOrderSn(refundOrderSn)
                                                                              // 订单状态
                                                                              .orderType(payInfo.getType())
                                                                              // 退款金额
                                                                              .refundFee(refundInfo.getPrice())
                                                                              // 退款状态
                                                                              .refundStatus(
                                                                                      refundInfoStatus == RefundInfo.ORDER_STATUS_SUCCEED ? NotifyBusinessRefundBO.REFUND_SUCCESS
                                                                                              : NotifyBusinessRefundBO.REFUND_FAIL)
                                                                              // 错误信息
                                                                              .errMsg(refundInfo.getFailMsg()).build();
        NotifyBusinessRequestBO notifyBusinessRequest = new NotifyBusinessRequestBO(orderSn, refundOrderSn,
                                                                                    NotifyBusinessRequestBO.NOTIFY_TYPE_REFUND,
                                                                                    notifyBusinessUrl, JsonMapper.toJson(notifyBusinessRefundBO));
        this.recoverNotifyBusinessService.asyncNotifyBusiness(notifyBusinessRequest);
    }

}
